/**
 *******************************************************************************
 * @FileName  : kv_type.h
 * @Author    : GaoQiu
 * @CreateDate: 2021-4-27
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */

#ifndef _KV_TYPE_H_
#define _KV_TYPE_H_

#include "utils/defs_types.h"
#include "kv_config.h"

typedef uint32_t kv_size_t;

typedef struct {
	int (*flash_init)(void);
	int (*flash_write)(uint32_t addr, uint8_t *pdata, uint32_t len);
	int (*flash_read)(uint32_t addr, uint8_t *pdata, uint32_t len);
	int (*flash_erase)(uint32_t addr, uint32_t blockNum);
}flash_opts_t;

typedef struct _block_info{
	struct _block_info   *pNext;
	kv_size_t             freeSize;
	uint8_t               state;
}block_info_t;

typedef struct{
	uint8_t         magic;
	uint8_t         state;
    uint8_t         RFU[2];
}block_hdr_t;

/* block state */
enum{
	KV_BLOCK_STATE_NONE  = 0xFF,
	KV_BLOCK_STATE_CLEAN = 0xEE,
	KV_BLOCK_STATE_USED  = 0xCC,
	KV_BLOCK_STATE_DIRTY = 0x88,
};
#define INVALID_BLOCK_STATE(state) (((state) != KV_BLOCK_STATE_USED) &&  \
                                   ((state) != KV_BLOCK_STATE_CLEAN) && \
                                   ((state) != KV_BLOCK_STATE_DIRTY))

typedef struct{
	uint8_t         magic;
	uint8_t         state;
	uint8_t         crc;
	uint8_t         keyLen;
	kv_size_t       valueLen;
	kv_size_t       originPos;
}item_hdr_t;

/* item state */
enum{
	KV_ITEM_STATE_VALID  = 0xAA,
	KV_ITEM_STATE_DELETE = 0x00,
};

/* key-value control block */
typedef struct {
	uint8_t         inited;
	uint8_t         gcFlag;
	uint8_t         gcBlockId;
	uint8_t         emptyBlockNum;
	uint8_t         dirtyMask;

    void           *lock;

    block_info_t   *pFreeBlock;
    block_info_t   *pUsedBlock;

#if CONFIG_KV_NEW_EN
    block_info_t    *block;
#else
    block_info_t    block[CONFIG_KV_BLOCK_NUM];
#endif
	kv_size_t       writeOffset;

#if CONFIG_KV_NEW_EN
	uint32_t        flashStartAddr;
	uint16_t        blockSize;
	uint8_t         blockNum;
#endif
}kv_t;

/* kv item */
typedef struct {
    item_hdr_t    hdr;
    uint8_t      *pdata;
    uint16_t      len;
    kv_size_t     pos;
} kv_item_t;

/* kv store */
typedef struct{
	uint8_t  *data;
	kv_size_t dataLen;
	kv_size_t pos;
}kv_store_t;

typedef int (*item_func_t)(kv_item_t *item, const char *key);

#define KV_BLOCK_HDR_SIZE  sizeof(block_hdr_t)
#define KV_ITEM_HDR_SIZE   sizeof(item_hdr_t)

#define KV_BLOCK_MAGIC_NUM 'G'
#define KV_ITEM_MAGIC_NUM  'Q'

#define KV_ITEM_HDR_STATE_POS   1
#define KV_BACKUP_BLOCK_NUM     1


#define KV_DELETE_CUR_FLAG      1
#define KV_DELTET_OLD_FLAG      2

#endif /* _KV_TYPE_H_  */
